package com.md.api.service.impl;

import com.aliyun.oss.model.StorageClass;
import com.md.api.common.config.RedisKeys;
import com.md.api.common.utils.AliOssUtil;
import com.md.api.dao.*;
import com.md.api.entity.*;
import com.md.api.entity.dto.ComposeCommitDto;
import com.md.api.entity.dto.ComposeQueryDto;
import com.md.api.entity.enums.OssStorageClassLevel;
import com.md.api.entity.enums.PayStatus;
import com.md.api.entity.enums.PictureStatus;
import com.md.api.entity.enums.UserStatus;
import com.md.api.entity.util.Page;
import com.md.api.common.utils.AESUtil;
import com.md.api.service.SysUserSevice;
import com.md.api.common.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * @Author liujie
 * @ClassName UserServiceImpl
 * @Date 2022年11月09日11:35
 **/

@Slf4j
@Service
public class SysUserServiceImpl implements SysUserSevice {

    @Resource
    TbOrderMapper orderMapper;
    @Resource
    SysUserMapper sysUserMapper;
    @Resource
    PdSkuMapper skuMapper;
    @Resource
    PdSpuMapper spuMapper;
    @Resource
    EvaluationRecordMapper evaluationRecordMapper;
    @Resource
    RedisUtil redisUtil;
    @Resource
    UserMapper userMapper;
    @Resource
    UserVipMapper userVipMapper;
    @Resource
    VipPropertiesMapper vipMapper;
    @Resource
    TbOrderVirtuallyMapper storageMapper;
    @Resource
    IndexMapper indexMapper;
    @Value("${common-key}")
    String commonKey;
    @Resource
    PhotoInfoMapper photoMapper;
    @Resource
    PictureInfoMapper pictureMapper;
    @Resource
    PhoneCodeConfirmLawMapper phoneCodeConfirmLawMapper;

    @Override
    public HttpResult indexCount() {
        Map<String,Object> map = new HashMap<>();
        map.put("todayPrice",indexMapper.getOrderPrice("today"));
        map.put("allPrice",indexMapper.getOrderPrice("all"));
        map.put("todayOrder",indexMapper.getOrderCount("today"));
        map.put("allOrder",indexMapper.getOrderCount("all"));
        List<UserCount> userTodayCount = indexMapper.getUserCount("all");
        if (!userTodayCount.stream().anyMatch(obj -> Objects.equals(obj.getUserType(), 1))){
            UserCount type1= new UserCount();
            type1.setUserType(1);
            type1.setCount(0);
            userTodayCount.add(type1);
        }
        if (!userTodayCount.stream().anyMatch(obj -> Objects.equals(obj.getUserType(), 2))){
            UserCount type1= new UserCount();
            type1.setUserType(2);
            type1.setCount(0);
            userTodayCount.add(type1);
        }
        if (!userTodayCount.stream().anyMatch(obj -> Objects.equals(obj.getUserType(), 0))){
            UserCount type1= new UserCount();
            type1.setUserType(0);
            type1.setCount(0);
            userTodayCount.add(type1);
        }
        map.put("userTodayCount",userTodayCount);
        List<UserCount> userAllCount = indexMapper.getUserCount("all");
        if (!userAllCount.stream().anyMatch(obj -> Objects.equals(obj.getUserType(), 1))){
            UserCount type1= new UserCount();
            type1.setUserType(1);
            type1.setCount(0);
            userAllCount.add(type1);
        }
        if (!userAllCount.stream().anyMatch(obj -> Objects.equals(obj.getUserType(), 2))){
            UserCount type1= new UserCount();
            type1.setUserType(2);
            type1.setCount(0);
            userAllCount.add(type1);
        }
        if (!userAllCount.stream().anyMatch(obj -> Objects.equals(obj.getUserType(), 0))){
            UserCount type1= new UserCount();
            type1.setUserType(0);
            type1.setCount(0);
            userAllCount.add(type1);
        }
        map.put("userAllCount",userAllCount);
        map.put("photoCount",indexMapper.getPhotoCount());
        map.put("pictureCount",indexMapper.getPictureCount());
        return new HttpResult(map);
    }

    @Override
    public HttpResult addUser( SysUser user) {
        try {
            SysUser dbuser = sysUserMapper.findByUserName(user.getUserName(),null);
            if (dbuser!=null){
                return HttpResult.fail("该用户名已被使用！");
            }
            String aesKey = AESUtil.randomCode();
            user.setUserRole("一般管理员");
            user.setAesKey(aesKey);
            user.setPassword(AESUtil.encrypt(user.getPassword(),aesKey));
            sysUserMapper.addUser(user);
        }catch (Exception e){
            e.printStackTrace();
            return HttpResult.fail("注册失败！");
        }
        return HttpResult.OK;
    }
    @Override
    public HttpResult updateUser( SysUser user) {
        sysUserMapper.updateUser(user);
        return HttpResult.OK;
    }

    @Override
    public HttpResult updatePass( SysUser user) {
        SysUser dbUser = sysUserMapper.getById(user.getUserId());
        String encrypt = AESUtil.decrypt(user.getOriginalPassword(), commonKey);
        if (!AESUtil.encrypt(encrypt,dbUser.getAesKey()).equalsIgnoreCase(dbUser.getPassword())){
            return HttpResult.fail("原密碼錯誤，請確認！");
        }
        if (StringUtils.isNotEmpty(user.getPassword())) {
            String newEncrypt = AESUtil.decrypt(user.getPassword(), commonKey);
            user.setPassword(AESUtil.encrypt(newEncrypt,dbUser.getAesKey()));
        }
        sysUserMapper.updatePass(user);
        return HttpResult.OK;
    }

    @Override
    public HttpResult sysUserLogin( SysUser user) {
        try {
            SysUser dbuser = sysUserMapper.findByUserName(user.getUserName(),0);
            String encrypt = AESUtil.decrypt(user.getPassword(), commonKey);
            String aesKey = dbuser.getAesKey();
            if (!AESUtil.encrypt(encrypt,aesKey).equalsIgnoreCase(dbuser.getPassword())){
                return HttpResult.fail("賬號或密碼錯誤，請確認！");
            }
            String loginToken = UUID.randomUUID().toString().replaceAll("-", "");
            dbuser.setToken(loginToken);
            dbuser.setPassword(null);
            dbuser.setAesKey(null);
            redisUtil.set(RedisKeys.getSysUserTokenInfoKey(loginToken),dbuser,3600*24);
            return new HttpResult(dbuser);
        }catch (Exception e){
            e.printStackTrace();
            return HttpResult.fail("登錄失敗！");
        }
    }



    @Override
    public HttpResult resetPass( SysUser sysUser) {
        SysUser dbUser = sysUserMapper.getById(sysUser.getUserId());
        dbUser.setPassword(AESUtil.encrypt("123456",dbUser.getAesKey()));
        sysUserMapper.updatePass(dbUser);
//        sysUserMapper.resetPass(commitDto.getUserIds(),DescUtil.encrypt("123456"));
        return HttpResult.OK;
    }

    @Override
    public HttpResult userPage(ComposeQueryDto compose){
            Page page = compose.getPage();
        try {
            page.initPagingData(SysUser.class);
            List<SysUser> userList= sysUserMapper.userPage(compose.getUserName(),compose.getNickName(),compose.getStatus());
//            for (SysUser user:userList){
//                user.setPassword(DescUtil.decryptor(user.getPassword()));
//            }
            page.setResult(userList);
        }catch (Exception e){
            e.printStackTrace();
        }
        return new HttpResult(page);
    }

    @Override
    public HttpResult deleteUser( ComposeCommitDto commitDto) {
        sysUserMapper.deleteUser(commitDto.getUserIds());
        return HttpResult.OK;
    }

    @Override
    public HttpResult enableUser( SysUser user) {
        sysUserMapper.updateUserStatus(user);
        return HttpResult.OK;
    }


    @Override
    public HttpResult evaluationPage( ComposeQueryDto qto) {
        Page page = qto.getPage();
        page.initPagingData(EvaluationRecord.class);
        List<EvaluationRecord> cartList = evaluationRecordMapper.getEvaRecord(qto.getIsFineEvaluation());
        page.setResult(cartList);
        return new HttpResult(page);
    }


    @Override
    public HttpResult spuPage( ComposeQueryDto qto) {
        Page page = qto.getPage();
        page.initPagingData(PdSpu.class);
        List<PdSpu> spuList = spuMapper.list(qto.getKeyword(),null);
        page.setResult(spuList);
        return new HttpResult(page);
    }


    @Override
    public HttpResult deleteSpu(ComposeQueryDto composeQueryDto) {
        //查询是否有人下过单
        PdSpu baseInfo = spuMapper.getBaseInfo(composeQueryDto.getSpuId());
        Integer saleCount = orderMapper.saledCount(composeQueryDto.getSpuId());
        if (baseInfo.getSaleStatus()==0||saleCount==0){
            return HttpResult.fail("该商品已售出过！");
        }else{
            spuMapper.deleteSpu(composeQueryDto.getSpuId());
            return HttpResult.OK;
        }
    }

    @Override
    public HttpResult skuPage( ComposeQueryDto qto) {
        Page page = qto.getPage();
        page.initPagingData(PdSku.class);
        List<PdSku> skuList = skuMapper.list(qto.getSpuId());
        page.setResult(skuList);
        return new HttpResult(page);
    }

    @Override
    public HttpResult orderPage(ComposeQueryDto qto) {
        Page page = qto.getPage();
        page.initPagingData(TbOrder.class);
        List<TbOrder> list = orderMapper.sysList(null,qto.getPayStatus(),qto.getOrderType(),qto.getPayType(),qto.getPayTimeStart(),qto.getPayTimeEnd());
        page.setResult(list);
        return new HttpResult(page);
    }

    @Override
    public HttpResult distributeOrder(ComposeQueryDto qto) {

        orderMapper.distributeOrder(qto.getOrderNo(),qto.getSkuId(),qto.getShippingName(),qto.getShippingCode(),qto.getDeliveryTime());

        TbOrder order = new TbOrder();
        order.setOrderNo(qto.getOrderNo());
        order.setPayStatus(PayStatus.TRANSPORT.value());
        orderMapper.updateOrder(order);
        return HttpResult.OK;
    }


    @Override
    public HttpResult vipOrderDetail(TbOrder order) {
        UserVip vip = userVipMapper.getByOrderNo(order.getOrderNo());
        return new HttpResult(vip);
    }

    @Override
    public HttpResult productOrderDetail(TbOrder order) {
        List<TbOrderDetail> details = orderMapper.orderDetail(order.getOrderNo());
        return new HttpResult(details);
    }

    @Override
    public HttpResult customPage(ComposeQueryDto qto) {
        Page page = qto.getPage();
        page.initPagingData(UserInfo.class);
        List<UserInfo> list = userMapper.list(qto.getNickName(),qto.getPhone(),qto.getEmail(),qto.getUserType(),qto.getStatus());
        for (UserInfo user:list){
            if (null!=user.getUseStorage()&&user.getUseStorage()>0){
                BigDecimal num1 = new BigDecimal(user.getUseStorage());
                BigDecimal num2 = new BigDecimal(1024*1024*1024);
                user.setUseStorage(num1.divide(num2,12, RoundingMode.HALF_UP).doubleValue());
            }
            user.setStorage(storageMapper.getTotalEffectiveStorage(user.getUserId()));
            user.setAiTimes(storageMapper.getTotalEffectiveAITimes(user.getUserId()));
            user.setFaceTimes(storageMapper.getTotalEffectiveFaceTimes(user.getUserId()));
            user.setCurrentVip(userVipMapper.getCurrentVip(user.getUserId()));
        }
        page.setResult(list);
        return new HttpResult(page);
    }


    @Override
    public HttpResult unlockCustom(UserInfo userInfo) {
        UserInfo user = userMapper.getByUserId(userInfo.getUserId());
        if(user.getStatus()!= UserStatus.THREE_LEVEL_LOCKED.value()){
            return HttpResult.fail("當前用戶未達到終極鎖定，不必解鎖！");
        }else{
            userMapper.updateStatus(userInfo.getUserId(),UserStatus.NORMAL.value());
            photoMapper.unlockUserPhoto(userInfo.getUserId());
            this.thawingPhoto(userInfo.getUserId());
        }
        return HttpResult.OK;
    }

    @Async
    public void thawingPhoto(String userId){
        List<PictureInfo> pictureList = pictureMapper.getMostPicByUserId(userId, OssStorageClassLevel.ColdArchive.value());
        for (PictureInfo picture:pictureList){
            //解冻冷归档文件
            if (StorageClass.ColdArchive.toString().equalsIgnoreCase(picture.getOssStorageClass())){
                AliOssUtil.thawingColdFile(picture.getPictureUrl());
                picture.setStatus(PictureStatus.THAWING.value());
                pictureMapper.updatePicture(picture);
            }
            //解冻深度冷归档文件
            if (StorageClass.DeepColdArchive.toString().equalsIgnoreCase(picture.getOssStorageClass())){
                AliOssUtil.thawingDeepColdFile(picture.getPictureUrl());
                picture.setStatus(PictureStatus.THAWING.value());
                pictureMapper.updatePicture(picture);
            }
        }
    }

    @Override
    public HttpResult vipPage(ComposeQueryDto qto) {
        Page page = qto.getPage();
        page.initPagingData(VipProperties.class);
        List<VipProperties> list = vipMapper.sysList();
        page.setResult(list);
        return new HttpResult(page);
    }

    @Override
    public HttpResult newVip(VipProperties vipProperties) {
        VipProperties weightVip = vipMapper.getWeightVip(vipProperties.getWeight());
        if (weightVip!=null){
            return HttpResult.fail("權重設置重複！");
        }
        //查看上一级vip
        VipProperties lastVip = vipMapper.getLastVip(vipProperties.getWeight());
        if (lastVip!=null){
            Double lastPrice = null!=lastVip.getCurrentPrice()?lastVip.getCurrentPrice():lastVip.getPrice();
            Double newPrice = null!=vipProperties.getCurrentPrice()?vipProperties.getCurrentPrice():vipProperties.getPrice();
            if (lastPrice>newPrice){
                return HttpResult.fail("新會員"+vipProperties.getServiceName()+"價格不應低於"+lastVip.getServiceName()+"的價格。（權重高的會員，價格也應該更高）");
            }
        }
        vipMapper.insert(vipProperties);
        return HttpResult.OK;
    }
    @Override
    public HttpResult setVip(VipProperties vipProperties) {
        vipMapper.update(vipProperties);
        return HttpResult.OK;
    }

    @Override
    public HttpResult addEvaluation( EvaluationRecord record) {
        evaluationRecordMapper.insert(record);
        return HttpResult.OK;
    }

    @Override
    public HttpResult deleteEvaluation( EvaluationRecord record) {
        evaluationRecordMapper.delete(record.getId());
        return HttpResult.OK;
    }

    @Override
    public HttpResult updateEvaluation( EvaluationRecord record) {
        evaluationRecordMapper.update(record);
        return HttpResult.OK;
    }


    @Override
    public HttpResult photoPage( ComposeQueryDto qto) {
        Page page = qto.getPage();
        page.initPagingData(PhotoInfo.class);
        List<PhotoInfo> list = photoMapper.selectAll(qto.getKeyword());
        page.setResult(list);
        return new HttpResult(page);
    }

    @Override
    public HttpResult picturePage( ComposeQueryDto qto) {
        Page page = qto.getPage();
        page.initPagingData(PictureInfo.class);
        List<PictureInfo> list = pictureMapper.getByPhotoId(qto.getPhotoId(),qto.getKeyword(),null);
        page.setResult(list);
        return new HttpResult(page);
    }


    @Override
    public HttpResult thawingPhoto(PhotoInfo photoInfo) {
        try {
            List<PictureInfo> list = pictureMapper.getByPhotoId(photoInfo.getPhotoId(),null,null);
            for (PictureInfo picture :list){
                if (StorageClass.Standard.toString().equalsIgnoreCase(picture.getOssStorageClass())
                    ||StorageClass.IA.toString().equalsIgnoreCase(picture.getOssStorageClass())){
                    continue;
                }
                //解冻归档文件
                if (StorageClass.Archive.toString().equalsIgnoreCase(picture.getOssStorageClass())){
                    AliOssUtil.thawingFile(picture.getPictureUrl());
                    picture.setStatus(PictureStatus.THAWING.value());
                    pictureMapper.updatePicture(picture);
                }
                //解冻冷归档文件
                if (StorageClass.ColdArchive.toString().equalsIgnoreCase(picture.getOssStorageClass())){
                    AliOssUtil.thawingColdFile(picture.getPictureUrl());
                    picture.setStatus(PictureStatus.THAWING.value());
                    pictureMapper.updatePicture(picture);
                }
                //解冻深度冷归档文件
                if (StorageClass.DeepColdArchive.toString().equalsIgnoreCase(picture.getOssStorageClass())){
                    AliOssUtil.thawingDeepColdFile(picture.getPictureUrl());
                    picture.setStatus(PictureStatus.THAWING.value());
                    pictureMapper.updatePicture(picture);
                }
            }
            photoInfo.setStatus(0);
            photoMapper.updatePhoto(photoInfo);
        }catch (Exception e){
            e.printStackTrace();
            return HttpResult.fail(e.getMessage());
        }
        return HttpResult.OK;
    }


    @Override
    public HttpResult deletePicture(PictureInfo picture) {
        pictureMapper.deleteByPictureId(picture.getPictureId());
        return HttpResult.OK;
    }

    @Override
    public HttpResult switchList() {
        List<SysSwitch> list = sysUserMapper.switchList();
        return new HttpResult(list);
    }

    @Override
    public HttpResult switchOpen(SysSwitch sysSwitch) {
        sysUserMapper.handleswitch(sysSwitch.getCode(),0);
        return HttpResult.OK;
    }

    @Override
    public HttpResult switchClose(SysSwitch sysSwitch) {
        sysUserMapper.handleswitch(sysSwitch.getCode(),-1);
        return HttpResult.OK;
    }

    @Override
    public HttpResult picShow() {
        List<SysPcConfiguration> cartList = pictureMapper.picShow();
        return new HttpResult(cartList);
    }

    @Override
    public HttpResult setPicShow(SysPcConfiguration pcConfiguration) {
        pictureMapper.setPicShow(pcConfiguration);
        return HttpResult.OK;
    }

    @Override
    public HttpResult docInstruction(SysPcDocInstruction instruction) {
        List<SysPcDocInstruction> cartList = pictureMapper.docInstruction(null,instruction.getCode());
        return new HttpResult(cartList);
    }

    @Override
    public HttpResult setDocShow(SysPcDocInstruction docInstruction) {
        pictureMapper.setDocShow(docInstruction);
        return HttpResult.OK;
    }

    @Override
    public HttpResult delDoc(SysPcDocInstruction pcConfiguration) {
        pictureMapper.delDoc(pcConfiguration.getId());
        return HttpResult.OK;
    }

    @Override
    public HttpResult newDoc(SysPcDocInstruction pcConfiguration) {
        if (pcConfiguration.getCode().equals("vip_instruction")){
            pcConfiguration.setName("會員服務介紹");
        }else if (pcConfiguration.getCode().equals("recharge_rules")){
            pcConfiguration.setName("充值規則介紹");
        } else {
            pcConfiguration.setName("文檔説明");
        }
        pictureMapper.newDoc(pcConfiguration);
        return HttpResult.OK;
    }


    @Override
    public HttpResult updatePhoneCode(PhoneCodeConfirmLaw record) {
        phoneCodeConfirmLawMapper.updateByPrimaryKey(record);
        return HttpResult.OK;
    }

    @Override
    public HttpResult deletePhoneCode(PhoneCodeConfirmLaw record) {
        phoneCodeConfirmLawMapper.deleteByPrimaryKey(record.getId());
        return HttpResult.OK;
    }

    @Override
    public HttpResult addPhoneCode(PhoneCodeConfirmLaw record) {
        phoneCodeConfirmLawMapper.insert(record);
        return HttpResult.OK;
    }

    @Override
    public HttpResult phoneCodePage(ComposeQueryDto qto) {
        Page page = qto.getPage();
        page.initPagingData(PhoneCodeConfirmLaw.class);
        List<PhoneCodeConfirmLaw> list = phoneCodeConfirmLawMapper.sysList(qto.getPhoneCode(), qto.getArea());
        page.setResult(list);
        return new HttpResult(page);
    }
}
